import json

from mall import settings
from urllib.parse import urlencode,parse_qs
from urllib.request import urlopen

class OauthQQ(object):

    def __init__(self,client_id=None,redirect_uri=None):

        self.client_id = client_id or settings.QQ_APP_ID
        self.redirect_uri = redirect_uri or settings.QQ_REDIRECT_URL

    def get_oauth_url(self, state):
        """

        :param state:
        :return:
        生成auth_url
        https://graph.qq.com/oauth2.0/authorize
        请求参数请包含如下内容：
        response_type   必须      授权类型，此值固定为“code”。
        client_id       必须      申请QQ登录成功后，分配给应用的appid。
        redirect_uri    必须      成功授权后的回调地址，必须是注册appid时填写的主域名下的地址，建议设置为网站首页或网站的用户中心。注意需要将url进行URLEncode。
        state           必须      client端的状态值。用于第三方应用防止CSRF攻击，成功授权后回调时会原样带回。请务必严格按照流程检查用户与state参数状态的绑定。
        scope              可选      scope=get_user_info

        """

        # 设置base_url,注意添加
        base_url = 'https://graph.qq.com/oauth2.0/authorize?'
        # 组织参数
        params = {
            'response_type': 'code',
            'client_id': self.client_id,
            'redirect_uri': self.redirect_uri,
            'state': state,
            'scope': 'get_user_info',
        }

        # 对参数进行urlencode,然后拼接url
        auth_url = base_url + urlencode(params)
        return auth_url

    def get_access_token(self,code):

        base_url = 'https://graph.qq.com/oauth2.0/token?'
        params = {
            'grant_type': 'authorization_code',
            'client_id': settings.QQ_APP_ID,
            'client_secret': settings.QQ_APP_KEY,
            'code': code,
            'redirect_uri': settings.QQ_REDIRECT_URL
        }

        url = base_url + urlencode(params)

        # 发送请求,获取响应
        response = urlopen(url)
        # 读取数据
        data = response.read().decode()

        query_params = parse_qs(data)

        # 获取token,并进行判断
        access_token = query_params.get('access_token')
        # print(access_token)
        # ['5F5893DBC5339A54B26AFD0A1312276F']
        if access_token is None:
            raise Exception('获取token失败')

        return access_token[0]



    def get_openid(self,access_token):

        # https://graph.qq.com/oauth2.0/me
        # GET
        # access_token        必须      在Step1中获取到的accesstoken。

        # 返回数据PC网站接入时，获取到用户OpenID，返回包如下：
        # callback( {"client_id":"YOUR_APPID","openid":"YOUR_OPENID"} );
        # openid是此网站上唯一对应用户身份的标识，网站可将此ID进行存储便于用户下次登录时辨识其身份，
        # 或将其与用户在网站上的原有账号进行绑定


        base_url = 'https://graph.qq.com/oauth2.0/me?'

        params = {
            'access_token': access_token
        }

        url = base_url + urlencode(params)

        # 发送请求,获取响应
        response = urlopen(url)

        response_data = response.read().decode()
        # 读取数据
        data = response.read().decode()

        try:
            data = json.loads(response_data[10:-4])

        except Exception as e:

            raise Exception('获取用户错误')

        openid = data.get('openid',None)

        return openid


